package com.yilin.platform.controller.user;

import com.google.gson.reflect.TypeToken;
import com.yilin.platform.base_core.application.*;
import com.yilin.platform.base_core.commons.annotation.Explain;
import com.yilin.platform.base_core.commons.annotation.NotNull;
import com.yilin.platform.base_core.commons.annotation.SkipLoginVerify;
import com.yilin.platform.base_core.commons.annotation.UserTarget;
import com.yilin.platform.base_core.commons.entity.AuthStatusData;
import com.yilin.platform.base_core.commons.utils.JsonUtil;
import com.yilin.platform.base_core.commons.utils.ParamUtil;
import com.yilin.platform.base_core.commons.utils.StringUtil;
import com.yilin.platform.base_core.tools.SMSUtil;
import com.yilin.platform.entity.enums.user.RoleType;
import com.yilin.platform.entity.enums.user.UserType;
import com.yilin.platform.entity.user.Account;
import com.yilin.platform.entity.user.Authority;
import com.yilin.platform.entity.user.Organize;
import com.yilin.platform.service.impl.user.AuthorityService;
import com.yilin.platform.service.user.IAccountService;
import com.yilin.platform.service.user.IAuthService;
import com.yilin.platform.service.user.IOrganizeService;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 用户管理
 */
@RestController
@RequestMapping("/user/account/")
public class AccountController extends BaseController {

    @Resource
    private IAccountService accountService;
    @Resource
    private IOrganizeService organizeService;
    @Resource
    private IAuthService authService;
    @Resource
    private AuthorityService authorityService;


    /**
     * 根据ID获取用户信息
     */
    @PostMapping("getAccountById")
    public ReturnData<Account> getAccountById(@Explain("用户ID") String accountId) {
        if(StringUtil.isEmpty(accountId))accountId=getLoginUser().getId();
        Account account = accountService.getAccountById(accountId);
        if (account == null) return jsonView(false, "未查询到该用户");
        return jsonView(true, "获取成功", account);
    }


    /**
     * 获取用户集合
     */
    @PostMapping("getAccountListByIds")
    public ReturnData<List<Account>> getAccountListByIds(String[] accountIds) {
        ParamUtil.isNull(accountIds, "用户名IDs参数为空");
        List<Account> accountList = accountService.getAccountListByIds(accountIds);
        return jsonView(true, "获取成功", accountList);
    }

    /**
     * 检查用户名
     */
    @PostMapping("checkUsername")
    public ReturnData<Boolean> checkUsername( String username) {
        ParamUtil.isNull(username, "用户名参数为空");
        if (username.length() < 6 || username.length() > 18) {
            return jsonView(false, "仅能设置6-18位账号");
        }
        Account account = accountService.getAccountByUsername(username);
        if (account != null) return jsonView(false, "账号已存在");
        return jsonView(true, "检查成功");
    }

    /**
     * 获取系统顶级用户
     */
    @PostMapping("getSystemAdminUser")
    @SkipLoginVerify
    public ReturnData<Account> getSystemAdminUser() {
        Account account = accountService.getSystemAdminUser();
        if (account == null) return jsonErrView("系统顶级用户获取失败");
        account.setPassword(null);
        account.setSafePassword(null);
        account.setFingerprintSecretKey(null);
        return jsonView(true, "检查成功", account);
    }

    /**
     * 获取平易林顶级用户
     */
    @PostMapping("getSystemYilinUser")
    @SkipLoginVerify
    public ReturnData<Account> getSystemYilinUser() {
        Account account = accountService.getSystemPlatformUser();
        if (account == null) return jsonErrView("系统平台用户获取失败");
        account.setPassword(null);
        account.setSafePassword(null);
        account.setFingerprintSecretKey(null);
        return jsonView(true, "获取成功", account);
    }

    /**
     * 获取用户所有下级账户信息
     * 根据平台ID获取下面所有用户
     */
    @PostMapping("getAccountChildPage")
    public ReturnData<PageData<Account>> getAccountChildPage(Account query, Integer page, Integer limit) {
        PageData<Account> map = accountService.getAccountChildPage(getLoginUser(),query, page, limit);
        return jsonView(SUCCESS_CODE, "获取成功", map);
    }

    /**
     * 获取司机列表
     * 根据平台ID获取下面所有用户
     */
    @PostMapping("getAccountDriverPage")
    public ReturnData<PageData<Account>> getAccountDriverPage(Account query, Integer page, Integer limit) {
        PageData<Account> map = accountService.getAccountDriverPage(getLoginUser(),query, page, limit);
        return jsonView(SUCCESS_CODE, "获取成功", map);
    }

    /**
     * 获取司机列表
     * 根据平台ID获取下面所有用户
     */
    @PostMapping("getAccountByManager")
    public ReturnData<List<Account>> getAccountByManager() {
        List<Account> map = accountService.getAccountByManager();
        return jsonView(SUCCESS_CODE, "获取成功", map);
    }



    /**
     * 设置安全密码
     */
    @PostMapping("updateSafePassword")
    public ReturnData<Object> updateSafePassword(String password,  String verCode) {
        ParamUtil.isNull(password,"新密码不能为空");
        ParamUtil.isNull(verCode,"验证码不能为空");
        if (!AppUtil.isNumeric(password) || password.length() != 6) {
            return jsonView(false, "安全密码必须是6位数纯数字！", null);
        }
        Account account = accountService.getAccountById(getLoginUser().getId());
        //检查手机验证码
        Map<String, Object> verifyCode = SMSUtil.verifyCode(account.getPhone(), verCode, SMSUtil.MsgType.updateSafePassword);
        if (!(Boolean) verifyCode.get(SMSUtil.SUCCESS)) {
            return jsonView(FAIL_CODE, (String) verifyCode.get(SMSUtil.MSG));
        }
        account.setSafePassword(AppUtil.md5(password));
        account.setSafeDisabled(false);
        account.setSafeFailCount(0);
        accountService.saveOrUpdateAccount(account, getLoginUser());
        UserUtil.updateLoginUser(account);
        return jsonView(true, "变更密码成功！");
    }

    /**
     * 变更密码
     */
    @PostMapping("updatePassword")
    @NotNull({"password", "verCode"})
    public ReturnData<Object> updatePassword(@Explain("密码") String password, @Explain("验证码") String verCode) {
        if (password.length() < 8) return jsonView(false, "密码设置不能低于8位！", null);
        Account account = accountService.getAccountById(getLoginUser().getId());
        //检查手机验证码
        Map<String, Object> verifyCode = SMSUtil.verifyCode(account.getPhone(), verCode, SMSUtil.MsgType.updatePassword);
        if (!(Boolean) verifyCode.get(SMSUtil.SUCCESS)) {
            return jsonView(FAIL_CODE, (String) verifyCode.get(SMSUtil.MSG));
        }
        account.setPassword(AppUtil.md5(password));
        accountService.saveOrUpdateAccount(account, getLoginUser());
        UserUtil.updateLoginUser(account);
        return jsonView(true, "变更密码成功！");
    }

    /**
     * 重置密码
     */
    @PostMapping("resettingPassword")
    public ReturnData<Object> resettingPassword(String accountId) {
        Account account = accountService.getAccountById(accountId);
        if (getLoginUser().getRoleType() != RoleType.manager) {
            return jsonErrView("您没有权限重置该用户密码");
        }
        if (!account.getOrganizeId().equals(getLoginUser().getOrganizeId())) {
            return jsonErrView("您没有权限重置该用户密码");
        }
        String newPassword = AppUtil.random(8);
        account.setPassword(AppUtil.md5(newPassword));
        accountService.saveOrUpdateAccount(account, getLoginUser());
        UserUtil.updateLoginUser(account);
        return jsonView(true, "变更密码成功！");
    }

    /**
     * 获取当前登录用户信息
     */
    @PostMapping("getLoginUserInfo")
    public ReturnData<Account> getLoginUserInfo(String accountId) {
        if(StringUtil.isEmpty(accountId))accountId=getLoginUser().getId();
        Account userInfo = accountService.getAccountById(accountId);
        if (userInfo == null) return jsonView(NO_LOGIN, "您的登录已失效，请重新登录");
        //查询字段----组织
        Organize organize = organizeService.getOrganizeById(userInfo.getOrganizeId());
        userInfo.setOrganize(organize);
        userInfo.setOrganizeName(organize.getOrganizeName());
        userInfo.setOrganizeLogo(organize.getOrganizeLogo());
        //查询字段----认证
        List<AuthStatusData> authStatusDataList = authService.getUserAuthStatus(userInfo);
        userInfo.setAuthStatusList(authStatusDataList);
        List<Authority> authorityList=authorityService.getAuthorityListByyAccountId(accountId);
        userInfo.setAuthorityList(authorityList);
        // ### 去除密码
        userInfo.setPassword(null);
        userInfo.setSafePassword(null);
        userInfo.setFingerprintSecretKey(null);
        userInfo.setSecretKey(null);
        UserUtil.updateLoginUser(userInfo);
        return jsonView(SUCCESS_CODE, true, "获取成功", userInfo);
    }

    /**
     * 修改用户信息
     */
    @PostMapping("updateAccount")
    public ReturnData<Object> updateAccount(Account param) {
        if (param.getId() == null) param.setId(getLoginUser().getId());
        Account localAccount = accountService.getAccountById(param.getId());
        if (localAccount == null) return jsonView(false, "未查询到该用户");
        if (getLoginUser().getUserType() != UserType.shipperUser) {
            if (getLoginUser().getRoleType() == RoleType.manager && !getLoginUser().getOrganizeId().equals(localAccount.getOrganizeId())) {
                return jsonView(false, "只能修改您自己组织下的账户信息");
            } else if (getLoginUser().getRoleType() == RoleType.employee && !getLoginUser().getId().equals(localAccount.getId())) {
                return jsonView(false, "只能修改您自己的信息");
            }
        }
        accountService.updateAccount(getLoginUser(), param, localAccount);
        UserUtil.updateLoginUser(param);
        return jsonView(true, "修改成功");
    }

    /**
     * 修改用户信息
     */
    @PostMapping("updateAccountAndOrganize")
    public ReturnData<Object> updateAccount(String accountJson,String organizeJson) {
        Account account= JsonUtil.jsonToObject(accountJson,new TypeToken<Account>(){});
        Organize organize= JsonUtil.jsonToObject(organizeJson,new TypeToken<Organize>(){});
        ParamUtil.isNull(account.getId(),"获取用户失败");
        if(!Objects.equals(account.getId(), getLoginUser().getId())){
            return jsonView(false, "您没有权限修改");
        }
        accountService.updateAccountAndOrganize(getLoginUser(), account, organize);
        return jsonView(true, "修改成功");
    }

    /**
     * 更改账户启用状态
     */
    @PostMapping(value = "updateUserStatus")
    @NotNull({"id", "userState"})
    public ReturnData<Object> updateUserStatus(Account account) {
        if (StringUtil.isEmpty(account.getId())) {
            return jsonView(false, "用户ID不能我空！");
        }
        Account local = accountService.getAccountById(account.getId());
        if (getLoginUser().getUserType().ordinal() >= local.getUserType().ordinal()) {
            return jsonView(false, "您没有权限操作该用户状态！");
        }
        local.setUserState(account.getUserState());
        accountService.saveOrUpdate(local);
        return jsonView(SUCCESS_CODE, "操作成功");
    }

    /**
     * 转让管理员
     */
    @PostMapping(value = "transferManager")
    @NotNull({"targetEmployeeId"})
    public ReturnData<Object> transferManager(String targetEmployeeId) {
        if (getLoginUser().getRoleType() != RoleType.manager) {
            return jsonView(false, "仅管理员可操作此功能！");
        }
        if (targetEmployeeId.equals(getLoginUser().getId())) {
            return jsonView(false, "您已经是管理员！");
        }
        Account manager = accountService.getAccountById(getLoginUser().getId());
        Account account = accountService.getAccountById(targetEmployeeId);
        if (!account.getOrganizeId().equals(getLoginUser().getOrganizeId())) {
            return jsonView(false, "仅能转让给同组织的成员账户！");
        }
        accountService.transferManager(manager, account);
        UserUtil.updateLoginUser(manager);
        UserUtil.updateLoginUser(account);
        return jsonView(SUCCESS_CODE, "操作成功");
    }

    /**
     * 用户注销/或管理员踢出账户
     */
    @PostMapping(value = "scrapAccount")
    @NotNull({"accountId"})
    public ReturnData<Object> scrapAccount(String accountId) {
        if (accountId != null && getLoginUser().getRoleType() != RoleType.manager) {
            return jsonView(false, "仅管理员可操作此功能！");
        }
        if (accountId == null) accountId = getLoginUser().getId();
        Account account = accountService.getAccountById(accountId);
        if (account.getRoleType() == RoleType.manager) {
            return jsonView(false, "管理员不可直接销户，请先解散组织！");
        }
        accountService.scrapAccount(getLoginUser(), account);
        return jsonView(SUCCESS_CODE, "操作成功");
    }

    /**
     * 停用/启用员工账户
     */
    @PostMapping(value = "enableOrDisableAccount")
    @NotNull({"accountId", "userState"})
    public ReturnData<Object> enableOrDisableAccount(String accountId, Account.UserState userState) {
        if (getLoginUser().getRoleType() != RoleType.manager) {
            return jsonView(false, "仅管理员可操作此功能！");
        }
        Account account = accountService.getAccountById(accountId);
        if (!getLoginUser().getOrganizeId().equals(account.getOrganizeId())) {
            return jsonView(false, "仅能操作自己的组织成员！");
        }
        if (account.getRoleType() == RoleType.manager) {
            return jsonView(false, "管理员不允许被停用！");
        }
        if (userState == null) {
            if (account.getUserState() == Account.UserState.disable) userState = Account.UserState.enable;
            if (account.getUserState() == Account.UserState.enable) userState = Account.UserState.disable;
        }
        account.setUserState(userState);
        accountService.updateById(account);
        UserUtil.updateLoginUser(account);
        return jsonView(SUCCESS_CODE, "操作成功");
    }



    /**
     * 更新API账户秘钥
     */
    @PostMapping("updateApiAccountKey")
    @NotNull({"accountId", "publicKey"})
    public ReturnData<Object> updateApiAccountKey(String accountId, String publicKey) {
//        Account account = accountService.getAccountById(accountId);
//        UserRole role = roleService.getUserRoleById(account.getOrganizeId(), account.getRoleId());
//        if (role.getRoleType() != RoleType.api) throw new BusinessException("秘钥仅限API类型用户");
//        account.setPublicKey(publicKey);
//        String secretKey = RedisClient.getInstance().hget(RedisKeys.ACCOUNT_API_PAIR_KEY, publicKey);
//        account.setSecretKey(secretKey);
//        accountService.saveOrUpdate(account);
//        UserUtil.updateLoginUser(account);
        return jsonView(true, "更新API账户秘钥成功");
    }

    /**
     * 修改员工角色
     */
    @PostMapping(value = "updateEmployeeRole")
    @NotNull({"accountId", "roleName"})
    public ReturnData<Object> updateEmployeeRole(String accountId, String roleName) {
        Account account = accountService.getAccountById(accountId);
        account.setRoleName(roleName);
        accountService.updateById(account);
        return jsonView(true, "操作成功");
    }
    /**
     * 验证安全密码
     * 验证时，密码和秘钥2选1即可
     */
    @PostMapping("verifySafePassword")
    @UserTarget
    public ReturnData<Object> verifySafePassword(@Explain("密码") String safePassword, @Explain("秘钥") String fingerprintKey) {
        if (StringUtil.isNotEmpty(safePassword)) accountService.verifySvePassword(getLoginUser(), safePassword);
        // 验证密码升级：服务调用密码成功后，会返回一串识别码，识别码用于处理业务逻辑
        String passCode = UserUtil.generatePassCode(getLoginUser());
        return jsonView(true, "验证成功！", passCode);
    }
    /**
     * 根据用户类型获取pushIds
     */
    @PostMapping(value = "getPushIdsByUserType")
    @NotNull({"userType"})
    @UserTarget({UserType.shipperUser, UserType.truckerUser})
    public ReturnData<String[]> getPushIdsByUserType(UserType userType) {
        String[] pushIds = accountService.getPushIdsByUserType(getLoginUser(), userType);
        return jsonView(true, "获取成功", pushIds);
    }

    /**
     * 根据用户类型获取pushIds
     */
    @PostMapping(value = "bindWeChat")
    @NotNull({"wechatId"})
    public ReturnData<String[]> bindWeChat(String wechatId) {
      Account account=accountService.getAccountById(getLoginUser().getWechatId());
      account.setWechatId(wechatId);
      accountService.updateById(account);
        return jsonView(true, "绑定成功");
    }

}
